<?php

namespace App\Model\Common;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use App\Model\Common\CategoryApi as Api;
use App\Model\Common\ProjectHistory as History;
use App\Model\Common\ProjectCategory as Category;
use App\Model\Common\ProjectErrorCode as ErrorCode;
use App\Model\Common\ProjectCommonParam as CommonParam;

class Project extends Common
{
    protected $cacheKey = 'ap:project:list';
    protected $userCacheKey = 'ap:user:project:list';
    protected $parentCacheKey = 'ap:user:project:list';
    protected $projectMenuKey = 'ap:project:menu:list';
    protected $parentKey = 'user_id';

    public function setPasswordAttribute($value)
    {
        $this->attributes['user_id'] = session('user:uid');
    }

    public function getMenu($id, $opt = [])
    {
        if (config('app.redis_on') && empty($opt['no_cache'])) {
            $data = Redis::hget($this->projectMenuKey, $uid);
        }
        if (empty($data)) {
            $data = self::find($id);
            if (!$data) {
                return [];
            }
            $data = $this->formatProjectMenuData($data, $opt);
            if (config('app.redis_on')) {
                Redis::hset($this->projectMenuKey, $id, json_encode($data));
            }
        } else {
            $data = json_decode($data, true);
        }

        return $data;
    }

    public function getUserProjectList($id, $opt = [])
    {
        if (config('app.redis_on') && empty($opt['no_cache'])) {
            $data = Redis::hget($this->userCacheKey, $uid);
        }
        if (empty($data)) {
            $data = self::where('user_id', $uid)->get();
            if (!$data) {
                return [];
            }
            $data = $this->formatOneDbData($data, $opt);
            if (config('app.redis_on')) {
                Redis::hset($this->userCacheKey, $id, json_encode($data));
            }
        } else {
            $data = json_decode($data, true);
        }

        return $data;
    }

    public function formatProjectMenuData($data, $opt = [])
    {
    }

    public function formatOneDbData($data, $opt = [])
    {
        // $projectid = is_object($data) ? $data->id : $data['id'];

        // $Category = new Category();
        // $categorys = $Category->where('status', 1)->where('project_id', $projectid)->get();
        // $data['categorys'] = is_object($categorys) ? $categorys->toArray() : $categorys;

        // if ($data['categorys']) {
        //     $Api = new Api();
        //     foreach ($data['categorys'] as $k => $v) {
        //         $apis = $Api->where('status', 1)->where('category_id', $v['id'])->get();
        //         $data['categorys'][$k]['apis'] = is_object($apis) ? $apis->toArray() : $apis;
        //     }
        // }
        if (!empty($opt['user']) && true === $opt['user']) {
            foreach ($data as $k => $v) {
                unset($data[$k]['description']);
                unset($data[$k]['intro']);
                unset($data[$k]['keywords']);
                unset($data[$k]['pic']);
            }
        }

        return $data;
    }

    public function refreshCache($obj, $mode)
    {
        if ('insert' === $mode) {
            $this->getOne($obj->id, ['no_cache' => true]);
            $this->getListByParentKey($obj->user_id, ['user' => true, 'no_cache' => true]);
        } elseif ('update' === $mode) {
            $this->getOne($obj->input('id'), ['no_cache' => true]);
            $this->getListByParentKey(session('user:uid'), ['user' => true, 'no_cache' => true]);
        }
        // $this->getListByParentKey(session('user:uid'), ['user' => true, 'no_cache' => true]);
    }

    public function oneDataFormat($data, $opt = [])
    {
        if (is_object($data)) {
            $data = $data->toArray();
        }
        $projectid = $data['id'];

        if (!empty($opt['need']) && is_array($opt['need'])) {
            if (in_array('historys', $opt['need'])) {
                $History = new History();
                $historys = $History->where('status', 1)->where('project_id', $projectid)->get();
                $data['historys'] = $historys;
            }
            if (in_array('common_params', $opt['need'])) {
                $Common = new CommonParam();
                $commons = $Common->where('status', 1)->where('project_id', $projectid)->get();
                $data['common_params'] = $commons;
            }
            if (in_array('error_codes', $opt['need'])) {
                $Error = new ErrorCode();
                $errors = $Error->where('status', 1)->where('project_id', $projectid)->get();
                $data['error_codes'] = $errors;
            }
            if (in_array('categorys', $opt['need'])) {
                $Category = new Category();
                $categorys = $Category->where('status', 1)->where('project_id', $projectid)->field('id,title')->get();
                $data['categorys'] = is_object($categorys) ? $categorys->toArray() : $categorys;

                if ($data['categorys']) {
                    $Api = new Api();
                    foreach ($data['categorys'] as $k => $v) {
                        $apis = $Api->where('status', 1)->where('category_id', $v['id'])->field('id,title,description')->get();
                        $data['categorys'][$k]['apis'] = is_object($apis) ? $apis->toArray() : $apis;
                    }
                }
            }
        }

        if (!empty($opt['module'])) {
            if ('console' === $opt['module']) {
                $Common = new CommonParam();
                $Error = new ErrorCode();
                $History = new History();
                $commons = $Common->where('status', 1)->where('project_id', $projectid)->get();
                $errors = $Error->where('status', 1)->where('project_id', $projectid)->get();
                $historys = $History->where('status', 1)->where('project_id', $projectid)->get();
                $data['common_params'] = $commons;
                $data['error_codes'] = $errors;
                $data['historys'] = $historys;
            }
            // if ('project' === $opt['module']) {
            //     $Category = new Category();
            //     $categorys = $Category->where('status', 1)->where('project_id', $projectid)->field('id,title')->get();
            //     $data['categorys'] = is_object($categorys) ? $categorys->toArray() : $categorys;

            //     if ($data['categorys']) {
            //         $Api = new Api();
            //         foreach ($data['categorys'] as $k => $v) {
            //             $apis = $Api->where('status', 1)->where('category_id', $v['id'])->field('id,title')->get();
            //             $data['categorys'][$k]['apis'] = is_object($apis) ? $apis->toArray() : $apis;
            //         }
            //     }
            // }
        }

        return $data;
    }

    public function add($data, $opt = [])
    {
        DB::beginTransaction();
        $Common = new CommonParam();
        $Error = new ErrorCode();
        try {
            $this->fillData($data)->save();

            if (!empty($data['common_param'])) {
                $len = count($data['common_param']);
                $common = [];
                for ($i = 0; $i < $len; ++$i) {
                    $common[$i]['param'] = $data['common_param'][$i];
                    $common[$i]['type'] = $data['common_type'][$i];
                    $common[$i]['limited'] = $data['common_limited'][$i];
                    $common[$i]['required'] = $data['common_required'][$i];
                    $common[$i]['description'] = $data['common_description'][$i];
                    $common[$i]['project_id'] = $this->id;
                }
                if ($common) {
                    $Common->insert($common);
                }
            }

            if (!empty($data['error_code'])) {
                $len = count($data['error_code']);
                $error = [];
                for ($i = 0; $i < $len; ++$i) {
                    $error[$i]['code'] = $data['error_code'][$i];
                    $error[$i]['title'] = $data['error_title'][$i];
                    $error[$i]['description'] = $data['error_description'][$i];
                    $error[$i]['project_id'] = $this->id;
                }
                if ($error) {
                    $Error->insert($error);
                }
            }

            DB::commit();
        } catch (\Illuminate\Database\QueryException $e) {
            DB::rollBack();
            $this->error = $e->errorInfo[2];

            return false;
        }

        return true;
    }

    public function edit($data, $opt = [])
    {
        $request = request();
        $uid = session('user:uid');
        DB::beginTransaction();
        $Common = new CommonParam();
        $Error = new ErrorCode();
        try {
            $projectData = $request->only($this->getColumns());
            if (!empty($data['pic']) && is_string($data['pic'])) {
                $projectData['pic'] = $data['pic'];
            }
            $this->where('id', $data['id'])->where('user_id', $uid)->update($projectData);

            //更新公共参数
            if (!empty($data['common_param'])) {
                $len = count($data['common_param']);
                $len_id = !empty($data['common_param_id']) ? count($data['common_param_id']) : 0;
                $old_commons = [];
                for ($i = 0; $i < $len_id; ++$i) {
                    $old_commons[$i]['id'] = $data['common_param_id'][$i];
                    $old_commons[$i]['param'] = $data['common_param'][$i];
                    $old_commons[$i]['type'] = $data['common_type'][$i];
                    $old_commons[$i]['limited'] = $data['common_limited'][$i];
                    $old_commons[$i]['required'] = $data['common_required'][$i];
                    $old_commons[$i]['description'] = $data['common_description'][$i];
                }
                foreach ($old_commons as $common) {
                    $Common->where('id', $common['id'])->update($common);
                }
                //新增公共参数
                if ($len - $len_id > 0) {
                    $new_commons = [];
                    for ($i = $len_id; $i < $len; ++$i) {
                        $new_commons[$i]['param'] = $data['common_param'][$i];
                        $new_commons[$i]['type'] = $data['common_type'][$i];
                        $new_commons[$i]['limited'] = $data['common_limited'][$i];
                        $new_commons[$i]['required'] = $data['common_required'][$i];
                        $new_commons[$i]['description'] = $data['common_description'][$i];
                        $new_commons[$i]['project_id'] = $data['id'];
                    }
                    $Common->insert($new_commons);
                }
            }

            //更新错误码
            if (!empty($data['error_code'])) {
                $len = count($data['error_code']);
                $len_id = !empty($data['error_code_id']) ? count($data['error_code_id']) : 0;
                $old_errors = [];
                for ($i = 0; $i < $len_id; ++$i) {
                    $old_errors[$i]['id'] = $data['error_code_id'][$i];
                    $old_errors[$i]['code'] = $data['error_code'][$i];
                    $old_errors[$i]['title'] = $data['error_title'][$i];
                    $old_errors[$i]['description'] = $data['error_description'][$i];
                }
                foreach ($old_errors as $error) {
                    $Error->where('id', $error['id'])->update($error);
                }

                //新增错误码
                if ($len - $len_id > 0) {
                    $new_errors = [];
                    for ($i = $len_id; $i < $len; ++$i) {
                        $new_errors[$i]['code'] = $data['error_code'][$i];
                        $new_errors[$i]['title'] = $data['error_title'][$i];
                        $new_errors[$i]['description'] = $data['error_description'][$i];
                        $new_errors[$i]['project_id'] = $data['id'];
                    }
                    $Error->insert($new_errors);
                }
            }

            DB::commit();
        } catch (\Illuminate\Database\QueryException $e) {
            DB::rollBack();
            $this->error = $e->errorInfo[2];

            return false;
        }
    }
}
